package com.flyqiu.common.enums;


import com.flyqiu.common.clazz.FlyQiuClassTools;
import com.flyqiu.common.dict.FlyQiuDicData;
import com.flyqiu.common.dict.FlyQiuDictTools;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 枚举类型工具类
 */
public class FlyQiuEnumTools {
    /**
     * 获取枚举字典
     *
     * @param clazz 枚举类型
     * @return <code>List&lt;FlyQiuDicData&gt;</code>
     */
    public static List<FlyQiuDicData> getEnumDic(Class<?> clazz) {
        return getEnumDic(clazz, new ArrayList<>());
    }

    /**
     * 获取枚举字典
     *
     * @param clazz          枚举类型
     * @param disabledValues 禁用的值
     * @return <code>List&lt;FlyQiuDicData&gt;</code>
     */
    public static List<FlyQiuDicData> getEnumDic(Class<?> clazz, List<String> disabledValues) {
        if (!clazz.isEnum()) throw new RuntimeException("class:" + clazz.getName() + " is not enum");
        Object[] enumConstants = clazz.getEnumConstants();
        List<FlyQiuDicData> list = new ArrayList<>();
        if (disabledValues == null) {
            disabledValues = new ArrayList<>();
        }

        if (FlyQiuClassTools.isNotForm(clazz, FlyQiuBaseEnum.class)) {
            for (Object obj : enumConstants) {
                String val = obj.toString();
                list.add(new FlyQiuDicData(val, val, disabledValues.contains(val)));
            }
            return list;
        }
        List<? extends FlyQiuBaseEnum<?>> collect = Arrays.stream(enumConstants).map(e -> (FlyQiuBaseEnum<?>) e).collect(Collectors.toList());
        return FlyQiuDictTools.getDictData(collect);
    }

    /**
     * 根据value 获取枚举类型
     *
     * @param enumClazz 枚举类型
     * @param value     枚举值
     * @param <T>       枚举类型
     * @return 返回枚举
     */
    @SuppressWarnings("uncheck")
    public static <T extends FlyQiuBaseEnum<?>> T findEnumByValue(Class<T> enumClazz, Object value) {
        if (value == null) {
            return null;
        }
        FlyQiuBaseEnum<?>[] enumConstants = enumClazz.getEnumConstants();
        for (FlyQiuBaseEnum<?> e : enumConstants) {
            if (e.getValue().equals(value)) {
                //noinspection unchecked
                return (T) e;
            }
        }
        return null;
    }

    /**
     * 查找枚举
     *
     * @param enumClazz 枚举类型
     * @param value     枚举值
     * @param defEnum   默认返回枚举
     * @param <T>       枚举类型
     * @return 枚举实例
     */
    public static <T extends FlyQiuBaseEnum<?>> T findEnumByValue(Class<T> enumClazz, Object value, T defEnum) {
        if (value == null) {
            return defEnum;
        }
        FlyQiuBaseEnum<?>[] enumConstants = enumClazz.getEnumConstants();
        for (FlyQiuBaseEnum<?> e : enumConstants) {
            if (e.getValue().equals(value)) {
                //noinspection unchecked
                return (T) e;
            }
        }
        return defEnum;
    }
}
